package com.heima.behavior.service.Impl;

import com.alibaba.fastjson.JSON;
import com.heima.apis.article.IArticleClient;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.behavior.service.BehaviorService;
import com.heima.common.redis.CacheService;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.common.constants.BeHaviorConstants;
import com.heima.model.common.constants.HotArticleConstants;
import com.heima.model.common.dtos.app.LikesBehaviorDto;
import com.heima.model.common.dtos.app.ReadBehaviorDto;
import com.heima.model.common.dtos.app.UnLikesBehaviorDto;
import com.heima.model.common.dtos.common.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.common.mess.UpdateArticleMess;
import com.heima.utils.thread.AppThreadLocalUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

@Service
public class BehaviorServiceImpl implements BehaviorService {
    @Autowired
    private CacheService cacheService;
    @Autowired
    private IArticleClient articleClient;
    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;
    /**
     * 用户不喜欢功能
     * @param dto
     * @return
     */
    @Override
    public ResponseResult unlikesBehavior(UnLikesBehaviorDto dto) {
        String userId = AppThreadLocalUtil.getUser().getId().toString();
        if (StringUtils.isEmpty(userId)||userId.equals("0")) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        if(dto==null||dto.getArticleId()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //组装key
        String key=BeHaviorConstants.UNLIKE_ARTICLE+dto.getArticleId()+":";
        //判断操作类型
        if(dto.getType()==0){
            //不喜欢,如果用户已经设置不喜欢操作，则提醒不可重复设置
            if(cacheService.hGet(key,userId)!=null){
                return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,"已设置不喜欢，请勿重复操作");
            }
            cacheService.hPut(key,userId,JSON.toJSONString(dto));
        }else{
            //取消不喜欢,如果用户未设置不喜欢，则无法取消
            if(cacheService.hGet(key,userId)==null){
                return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,"未设置不喜欢，无法取消");
            }
            cacheService.hDelete(key,userId);
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }



    /**
     * 文章阅读量统计
     * @param dto
     * @return
     */
    @Override
    public ResponseResult readBehavior(ReadBehaviorDto dto) {
        //检验是否登录
        String userId = AppThreadLocalUtil.getUser().getId().toString();
        if(userId.equals("0")){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //检验参数
        if(dto==null||dto.getArticleId()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //设置key
        String key=BeHaviorConstants.READ_ARTICLE+dto.getArticleId()+":";
        //获取该用户阅读量，如果为不存在，则添加，如果存在，则在原阅读量基础上加count
        String readString=(String) cacheService.hGet(key,userId);
        if(readString!=null){
            //则在原阅读量基础上加count
            ReadBehaviorDto readBehaviorDto = JSON.parseObject(readString, ReadBehaviorDto.class);
            dto.setCount(dto.getCount()+readBehaviorDto.getCount());
        }
        cacheService.hPut(key,userId,JSON.toJSONString(dto));
        //使用kafka发消息通知数据库更改阅读量
        UpdateArticleMess updateArticleMess = new UpdateArticleMess();
        updateArticleMess.setArticleId(dto.getArticleId());
        updateArticleMess.setType(UpdateArticleMess.UpdateArticleType.VIEWS);
        updateArticleMess.setAdd(1);
        kafkaTemplate.send(HotArticleConstants.HOT_ARTICLE_SCORE_TOPIC,JSON.toJSONString(updateArticleMess));
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 点赞功能
     * @param dto
     * @return
     */
    @Override
    public ResponseResult likesBehavior(LikesBehaviorDto dto) {
        //判断是否登录
        String userId = AppThreadLocalUtil.getUser().getId().toString();
        if(userId.equals("0")){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //检验参数
        if(dto.getArticleId() == null||checkParam(dto)){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //使用kafka发消息通知数据库更改阅读量
        UpdateArticleMess mess = new UpdateArticleMess();
        mess.setArticleId(dto.getArticleId());
        mess.setType(UpdateArticleMess.UpdateArticleType.LIKES);
        //拼接key
        String key="";
        //根据点赞的类型设计key
        if(dto.getType()==0){
            //点赞文章
            key= BeHaviorConstants.LIKE_ARTICLE+dto.getArticleId()+":";
        }else if(dto.getType()==1){
            //点赞评论
            key= BeHaviorConstants.LIKE_COMMENT+dto.getArticleId()+":";
        }else if(dto.getType()==2){
            //点赞动态
            key= BeHaviorConstants.LIKE_DYNAMIC+dto.getArticleId()+":";
        }
        //判断操作行为
        if(dto.getOperation()==0){
            //如果操作是点赞，则判断redis是否有相同的key
            if(cacheService.hGet(key, userId)!=null){
                return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,"已点赞，请重复操作");
            }
            cacheService.hPut(key,userId, JSON.toJSONString(dto));
            mess.setAdd(1);
        }else{
            //如果是取消点赞，则删除key下的该用户的信息
            if(cacheService.hGet(key, userId)==null){
                return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,"未点赞，无法取消");
            }
            cacheService.hDelete(key,userId);
            mess.setAdd(-1);
        }
        kafkaTemplate.send(HotArticleConstants.HOT_ARTICLE_SCORE_TOPIC,JSON.toJSONString(mess));
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
    /**
     * 检查参数
     *
     * @return
     */
    private boolean checkParam(LikesBehaviorDto dto) {
        if (dto.getType() > 2 || dto.getType() < 0 || dto.getOperation() > 1 || dto.getOperation() < 0) {
            return true;
        }
        return false;
    }
}
